//created by suicide penkovskiy shifter
//9.8.12
//svn repository: http://code.google.com/p/small-game-1/source/list
//new svn repo: http://code.google.com/p/test-subject/

/*
Organization:

Basic functions/global definitions belong in the main section of code in main.dm & globals.dm
Example: world/New(), do_abs(52)

Functions belonging to specific systems, ex black market value calculation; will have its own .dm file in the sub-folder code\.
definitions/variables belonging to that system will also be located in this file. If it gets too big it will be re-organized.

atoms will have their own folder based on its type, there is a folder code\mob, as well as code\mob\rat
the defines.dm located in these folders are definitions belonging to that type, as well as CHILD functions.
	NO NEW PROC DEFINITONS ARE CREATED HERE
	example; code\mob\defines.dm <- will have Login functions
new function definitions for the sub-types have their own .dm file. example: code\mob\life().dm contains the new code for mob.life()

examples;

atom
	defines.dm
	add_fprint().dm

	mob
		defines.dm
			->add_fprint() //is defined in defines, not created in another .dm file
		is_human().dm		//a proc going to belong to all mob types, wouldn't make sense to put this in /atom/defines.dm

		human
			defines.dm
				->is_human()	//re-defined in this file, because it is now a CHILD function
	obj
		defines.dm
			->Move()
		force_drop().dm

		weapons
			defines.dm
				->force_drop()
			kill().dm

			//if needed, create a sub-folder to contain all the types of weapons available
			sub_type
				lathe.dm
				knife.dm
				cleaver.dm
*/

world
	fps = 15
	icon_size = 32
	view = 6
	turf = /turf/tile
	mob = /mob/new_player

	name = "oehaber"
	Del()
		wlog("deleting world")
		..()
	New()
		..()
		speech_log = file("logs/[time2text(world.realtime,"MM_DD_YY")].txt")
		wlog = file("world_logs.txt")
		//#debug just for now it only stores one session
		if(fexists(wlog))
			fdel(wlog)
		wlog("world initializing")

		//set the hub
		set_hub()

		//begin world loop.
		spawn()
			wlog("world begin loop, now authorized for login")
			while(world)
				sleep(10)

				for(var/mob/M in world)
					if(ismob(M))
						M.life()

				world_ticks++



proc
	game_del(atom/a)
	///	var/list/built_in = list("type","parent_type","gender","verbs","vars","group","locs")
	//	for(var/v in a.vars)
	//		if(!(v in built_in))
	//			a.vars[v] = null
	//	del a
		a.Del()



	//used to create a browser window of debug texts,
	ret_debug(text, ret=0,mob/who)
		return_debug += text

		if(ret && who && return_debug.len)
			who << browse(list2text(return_debug,"<br>"), "window=retde;size=550x550")
			return_debug = list()
	debug(t,list/who)
		if(who)
			who<<"[d_t] [t]"
		else
			debugger<<"[d_t] [t]"
	wlog(t)
		if(wlog_status)
			wlog<<"[get_time()] [t];"
	slog(t)
		if(slog_status)
			speech_log<<"[get_time()] [t];"

	play_ambience(mob/who, sound)
		//WIP
		if(!who)
			debug("no mob in play_ambience()")
			return
		if(!sound)
			debug("no sound in play_ambience: [who.name]")
			return
		who<<sound(sound, 1, 1, 1, 25)

	play_sound(atom/where, sound, range=5)

		if(!where)
			wlog("tried to play sound with no where argument")
			return

		if(!sound)
			debug("[d_t] no sound; play_sound()")
			return

		if(!range && ismob(where))
			where<<sound(sound, 0, 0, SFX_CHANNEL,50)
			return


		var/turf/w2 = get_turf(where)
		if(!w2)
			debug("[d_t] play_sound, can't find atom's turf location,")
			return

		//play sound to viewers in range
		for(var/mob/M in viewers(range,w2))

			//loop over them if they have sound turned off
			if(!M.sound)
				continue
			var/sound/s = sound(sound, 0, 0, SFX_CHANNEL)
			if(isturf(w2))
				s.x = (w2.x-M.x)
				s.y = (w2.y-M.y)
				s.z = (w2.z-M.z)
			M<<s

	set_hub()
		var/f = file("config/hub.txt")
		if(!fexists(f))
			f<<"suicideshifter.smallgame"
			f<<"nopassword"
			f<<"default status, this status can only be one line long, thx."
			debug("hub.txt created")
			return
		var/bulk = file2text(f)
		var/hub_path = copytext(bulk, 1, findtext(bulk,"\n") )
		bulk = copytext(bulk, findtext(bulk, "\n")+1 )


		var/hub_password = copytext(bulk, 1, findtext(bulk,"\n") )
		bulk = copytext(bulk, findtext(bulk, "\n")+1)

		var/world_status = copytext(bulk, 1, findtext(bulk,"\n") )

		world.hub = hub_path
		world.hub_password = hub_password
		world.status = world_status
		debug("Hub status set.")

	get_time(html=0)
		var/t = time2text(world.timeofday, "MM/DD=hh:mm:ss")
		return "[html ? "<tr><td>[t]</td><td>" : "[t]"]"


	handle_bans()

	handle_admins(mob/m)
		if(!m.client) return

		if(m.client.ckey in admins + guides)
			m.verbs += typesof(/mob/debug/verb)

	//returns any atom's location in a turf
	get_turf(atom/where)
		while(isloc(where))
			if(isturf(where))
				return where
			where = where.loc
		return null

	ispowerof2(v)
		return v && !(v & (v - 1))
	//caps v in between high(y) and low(x)
	minmax(x,v,y)
		v = max(v, x)
		v = min(v, y)
		return v

	//returns false if a number is positive, zero counts as positive
	find_sign(v)
		return !(v < 0)
	//returns the center range of two numbers
	average_number(x,y)
		return (x & y) + ((x ^ y) >> 1)

proc/hex2num(hex)
	if (!hex || !istext(hex) )
		return

	var/num = 0
	var/power = 0
	var/i = length(hex)

	while(i > 0)
		var/char = copytext(hex, i, i + 1)
		switch(char)
			if("0")
			if("9", "8", "7", "6", "5", "4", "3", "2", "1")
				num += text2num(char) * 16 ** power
			if("a", "A") 	num += 16 ** power * 10
			if("b", "B")	num += 16 ** power * 11
			if("c", "C")	num += 16 ** power * 12
			if("d", "D")	num += 16 ** power * 13
			if("e", "E")	num += 16 ** power * 14
			if("f", "F")	num += 16 ** power * 15
		power++
		i--
	return num

//Returns the hex value of a number
proc/num2hex(num, placeholder=2)
	.="0"
	if(!num || !isnum(num))
		//if num doesnt exist, or if num exists but isnt number format
		return

	var/hex = ""
	var/i = 0
	while(16 ** i < num)
		i++
	var/power = i - 1
	while(power >= 0)
		var/val = round(num / 16 ** power)
		num -= val * 16 ** power
		switch(val)
			if(9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
				hex += "[val]"
			if(10)	hex += "A"
			if(11)	hex += "B"
			if(12)	hex += "C"
			if(13)	hex += "D"
			if(14)	hex += "E"
			if(15)	hex += "F"

		power--

	while(length(hex) < placeholder)
		hex = "0[hex]"
	return hex


proc/text2list(text, separator, case=FALSE)

	var/list/textList = list()
	var/textlength = length(text)
	var/separatorlength = length(separator)

	var/searchPosition = 1
	var/findPosition = 1
	var/it = 0

	while(searchPosition < textlength+1)
		it++
		if(it >= 999)
			wlog("text2list aborting infinite loop at iteration 999")
			debug("text2list CRASH, preventing infinite loop")
			break
		findPosition = case ? findtext(text, separator, searchPosition, 0) : findtextEx(text, separator, searchPosition, 0)
		if(!findPosition && (searchPosition < textlength+1))
			//theres one more element at the end of the list
			findPosition = textlength+1

		textList += copytext(text, searchPosition, findPosition)
		searchPosition = findPosition + separatorlength
	return textList


proc/list2text(list/what, separator=";")
	if(!what || !what.len)
		return

	var/count = 1,total = what.len
	do
		. += "[what[count]][count<total?separator :]"
		count++
	while(count <= total)
	return


proc/file2list(file_path, separator)
	var/file
	if(!separator)
		separator = "\n"

	file = isfile(file_path)?file_path : file(file_path)
	return text2list(file2text(file), separator)
